package com.yh.base.common;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.yh.base.util.ObjectUtil;


public class UploadFileServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;
	private final static Log log = LogFactory.getLog(UploadFileServlet.class);
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		try {
			req.setCharacterEncoding("UTF-8");
	
			// 是否包含上传文件
			if (ServletFileUpload.isMultipartContent(req)) {
				DiskFileItemFactory fac = new DiskFileItemFactory();
				ServletFileUpload du = new ServletFileUpload(fac);
				RequestContext r = new ServletRequestContext(req);
				List fileItems = du.parseRequest(r);
				
				// 取存储格式参数
				String isFileType = ObjectUtil.toString(GlobalConfig.newInstance().get("attach_save_type_file"));
				String isDataType = ObjectUtil.toString(GlobalConfig.newInstance().get("attach_save_type_data"));
				// 取文件存取路径
				String fileSaveDir = ObjectUtil.toString(GlobalConfig.newInstance().get("attach_file_dir"));
				
				// 附件信息
				Iterator iterator = fileItems.iterator();
				while (iterator.hasNext()) {
					FileItem fileItem = (FileItem) iterator.next();
					if (!fileItem.isFormField()) {
						// 附件
						if (fileItem.getName() != null && !"".equals(fileItem.getName().trim())) {
							InputStream inputStream = fileItem.getInputStream(); // 文件信息
							File file = new File(fileItem.getName());
							// 附件名称
							String fileName = file.getName();
							// 附件类型
							String contentType = fileItem.getContentType();
							// 附件长度
							int attachFileDataSize = inputStream.available(); // 字节
							String attachFileRealPath = "";

							log.debug("filename:" + fileName);
							log.debug("contentType:" + contentType);
							log.debug("attachFileDataSize:" + attachFileDataSize);
							
							//拿到文件seq
							WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
							JdbcTemplate jdbcTemplate = (JdbcTemplate) wac.getBean(ObjectUtil.toString(GlobalConfig.newInstance().get("ibatisTemplate_name")));
							String sqlSeqAttachFile = ObjectUtil.toString(GlobalConfig.newInstance().get("attach_sql_sequence"));
							long attachFileId = jdbcTemplate.queryForLong(sqlSeqAttachFile);
							
							if("Y".equalsIgnoreCase(isFileType.trim())) {
								// 需要存储文件格式
								try {
									// 准备目录
									String realPath = fileSaveDir + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "\\";
									createFolder(fileSaveDir);
									createFolder(realPath);
									String tmpName = req.getSession().getId() + "_" + attachFileId + "_" + fileName;
									// 输出流
									attachFileRealPath = realPath + "\\" + tmpName;
									OutputStream bos = new FileOutputStream(attachFileRealPath);//建立一个上传文件的输出流
									
									int bytesRead = 0;
									byte[] buffer = new byte[8192];
									while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
										bos.write(buffer, 0, bytesRead);//将文件写入服务器
									}
									bos.close();
								}catch(Exception e){
									System.err.print(e);
								}
							}
							String saveSql = ObjectUtil.toString(GlobalConfig.newInstance().get("attach_sql_save_without_data"));
							if("Y".equalsIgnoreCase(isDataType.trim())) {
								// 需要存储数据库格式
								saveSql = ObjectUtil.toString(GlobalConfig.newInstance().get("attach_sql_save_with_data"));
							}
							// 存储用参数
							final long paramAttachFileId = attachFileId;
							final String paramFileName = fileName;
							final int paramAttachFileDataSize = attachFileDataSize;
							final String paramAttachFileRealPath = attachFileRealPath;
							final InputStream  paramInputStream = fileItem.getInputStream();
							final String saveType = isDataType;
							jdbcTemplate.execute(saveSql, new PreparedStatementCallback() {
								public Object doInPreparedStatement(PreparedStatement stmt) throws SQLException, DataAccessException {
									stmt.setObject(1, paramAttachFileId);
									stmt.setObject(2, paramFileName);
									stmt.setObject(3, paramAttachFileRealPath);
									if("Y".equalsIgnoreCase(saveType.trim())) {
										stmt.setBinaryStream(4, paramInputStream, paramAttachFileDataSize);
									}
									stmt.execute();
									return null;
								}
							});
							
							resp.setCharacterEncoding("UTF-8");
							resp.getWriter().write(""+attachFileId);
						}
					}
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @Title: createFolder
	 * @description: 创建目录
	 * @param folderName 目录名称
	 * @return File 目录对象
	 */
	public File createFolder(String folderName) {
		File folder = new File(folderName);
		if (folder.exists() && folder.isDirectory()) {
			return folder;
		}
		folder.mkdirs();
		return folder;
	}
}
